package channelAPI

import (
	"errors"
	"fmt"
	"gitee.com/fierce_wolf/go-fox-edge-common/commLogger"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedisRpc"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Chan"
)

type channelService struct {
	IExecute       IChannelServerExecute       // 执行主从半双工操作：上位机向设备问询，并等待设备的回答，直到设备响应或者超时
	IPublish       IChannelServerPublish       // 执行发布操作：上位机向设备单向发送报文，不需要等待设备的返
	IReport        IChannelServerReport        // 设备的主动上报消息：设备向上位机
	IOpenChannel   IChannelServerOpenChannel   // 打开通道
	ICloseChannel  IChannelServerCloseChannel  // 关闭通道
	IManageChannel IChannelServerManageChannel // 对通道进行管理操作
	reportEvent    *Chan.Event
}

func (e *channelService) Execute(requestVO *commRedisRpc.ChannelRequestVO) (rtn *commRedisRpc.ChannelRespondVO, err error) {
	if e.IExecute == nil {
		return nil, errors.New("该channel不支持主从问答方式")
	}

	defer func() {
		if r := recover(); r != nil {
			message := fmt.Sprintf("publish()捕获到异常:%v", r)
			err = errors.New(message)
			commLogger.Error(message)
		}
	}()

	return e.IExecute.Execute(requestVO)
}

func (e *channelService) Publish(requestVO *commRedisRpc.ChannelRequestVO) (err error) {
	if e.IPublish == nil {
		return errors.New("该channel不支持CallPublish方式")
	}

	defer func() {
		if r := recover(); r != nil {
			message := fmt.Sprintf("publish()捕获到异常:%v", r)
			err = errors.New(message)
			commLogger.Error(message)
		}
	}()

	return e.IPublish.Publish(requestVO)
}

func (e *channelService) NotifyReport() {
	e.reportEvent.Notify(0)
}

func (e *channelService) GetReports() (rnt []*commRedisRpc.ChannelRespondVO, err error) {
	if e.IReport == nil {
		return nil, errors.New("该channel不支持Publish方式")
	}

	defer func() {
		if r := recover(); r != nil {
			message := fmt.Sprintf("GetReports()捕获到异常:%v", r)
			err = errors.New(message)
			commLogger.Error(message)
		}
	}()

	// 等待取上报数据的信号
	e.reportEvent.Wait(60 * 1000)

	// 取上报数据
	return e.IReport.Report()
}

func (e *channelService) OpenChannel(channelName string, channelParam map[string]interface{}) (err error) {
	if e.IOpenChannel == nil {
		return errors.New("该channel不支持OpenChannel方式")
	}

	defer func() {
		if r := recover(); r != nil {
			message := fmt.Sprintf("通道打开失败:%v: %v", channelName, r)
			err = errors.New(message)
			commLogger.Error(message)
		}
	}()

	return e.IOpenChannel.OpenChannel(channelName, channelParam)
}

func (e *channelService) CloseChannel(channelName string, channelParam map[string]interface{}) (err error) {
	if e.ICloseChannel == nil {
		return errors.New("该channel不支持CloseChannel")
	}

	defer func() {
		if r := recover(); r != nil {
			message := fmt.Sprintf("通道关闭失败:%v: %v", channelName, r)
			err = errors.New(message)
			commLogger.Error(message)
		}
	}()

	return e.ICloseChannel.CloseChannel(channelName, channelParam)
}

func (e *channelService) ManageChannel(requestVO *commRedisRpc.ChannelRequestVO) (rnt *commRedisRpc.ChannelRespondVO, err error) {
	if e.IManageChannel == nil {
		return nil, errors.New("该channel不支持ManageChannel")
	}

	defer func() {
		if r := recover(); r != nil {
			message := fmt.Sprintf("ManageChannel()捕获到异常:%v", r)
			err = errors.New(message)
			commLogger.Error(message)
		}
	}()

	return e.IManageChannel.ManageChannel(requestVO)
}
